package modelo.AlgoHero;

import java.util.ArrayList;
import java.util.Iterator;

import modelo.Excepciones.*;

import org.w3c.dom.*;




public class Partitura implements Traducible {

	private ArrayList <Nota>notas;
	private Integer espacioLibre;
	
	/**
	 * Constructor de Partitura que no recibe parametros	
	 *  @autor santiago di Tada
	 */
	public Partitura (){
		notas = new ArrayList <Nota>();		
		this.espacioLibre = Duracion.getDuracion();
	}
	
	/**
	 * Recibe un nodo, que seria la partitura realiza la deserializacion y completa la partitura
	 *  TODO completar
	 *  @autor santiago di Tada
	 */
	public void Deserialize(Element partituraNode){	
		  NodeList nodeList = partituraNode.getElementsByTagName("nota");
		  if(nodeList != null && nodeList.getLength() > 0) {
			  for(int i = 0 ; i < nodeList.getLength();i++) 
			  {			 
				  Nota nota = new Nota();
				  //System.out.println("Nota"+i);	
				  nota.Deserialize((Element)nodeList.item(i));				  			 
				  this.notas.add(nota);				 	 			 
			  }
		  }				 
	}
	
	/**
	 * Metodo utilizado para agregar notas a la partitura.
	 * Verifica que en la partitura haya espacio suficiente para la nota
	 * De lo contrario lanza excepcion EspacioNoSuficienteEnPartitura
	 * @param nota
	 * @throws EspacioNoSuficienteEnPartitura
	 * @author Hernan G Gonzalez
	 */
	public void add(Nota nota) throws EspacioNoSuficienteEnPartitura{

		if (this.espacioLibre < nota.getDuracion()) throw new EspacioNoSuficienteEnPartitura ();
		this.espacioLibre = this.espacioLibre - nota.getDuracion();
		this.notas.add(nota);
		
	}
	
	/**
	 * Metodo utilizado para traducir la partitura actual.
	 * Devuelve una instancia de la clase Partitura Traducida
	 * @author Hernan G Gonzalez
	 */
	public ObjetoTraducido traducir() {
		
		PartituraTraducida partituraTraducida = new PartituraTraducida ();
		
		Iterator <Nota> i = this.notas.iterator();
		
		Nota notaActual;
		
		while (i.hasNext()){
			
			notaActual = i.next();
			
			Integer notaTraducida = notaActual.getDuracion();

			if (notaTraducida >1){
				
				partituraTraducida.add(FactoryElementos.crearElemento(TipoElementoReproducible.INICIAL));
				notaTraducida = notaTraducida - 1;
				
				while (notaTraducida >1 ){
					
					partituraTraducida.add(FactoryElementos.crearElemento(TipoElementoReproducible.MEDIO));
					notaTraducida = notaTraducida - 1;
				}
				partituraTraducida.add(FactoryElementos.crearElemento(TipoElementoReproducible.FINAL));
				notaTraducida = notaTraducida - 1;
				
			}
			if (notaTraducida == 1){
				partituraTraducida.add(FactoryElementos.crearElemento(TipoElementoReproducible.TOTAL));
			}
						
			if (notaTraducida < 0){
				int notaTraducidaPostiva = Math.abs(notaTraducida);
				for (int j=notaTraducidaPostiva;j>0;j--){
					
					partituraTraducida.add(FactoryElementos.crearElemento(TipoElementoReproducible.NULO));
					
				}
			}
		}

		return partituraTraducida;
	}
	
	/**
	 * Metodo utilizado para saber si hay notas 
	 * @author santiago di Tada
	 */
	public boolean isEmpty(){
		return this.notas.isEmpty();
	}


}
